package com.smart.manager.product.repository;


import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.smart.common.cache.CacheService;
import com.smart.common.entities.constant.ArcoTips;
import com.smart.common.entities.core.Page;
import com.smart.common.entities.domain.TaskResult;
import com.smart.common.entities.option.SelectOption;
import com.smart.manager.product.entities.body.RBasicCameraDetail;
import com.smart.manager.product.entities.enums.CameraDirection;
import com.smart.manager.product.entities.enums.CameraStatus;
import com.smart.manager.product.entities.models.BasicCameraDetail;
import com.smart.manager.product.entities.models.query.QBasicCameraDetail;
import com.smart.manager.task.CameraDetailTask;
import io.ebean.annotation.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 游戏管理  摄像头
 *
 * @author leo
 * @date 2023/09/13
 */
@Service
@Log4j2
@RequiredArgsConstructor
public class BasicCameraDetailRepository {

    private final CacheService cacheService;

    private final CameraDetailTask cameraTask;

    /**
     *获取 直播地址
     */
    private final static String LIVE  = "https://open.ys7.com/api/lapp/v2/live/address/get";
    /**
     *修改设备名称地址
     */
    private final static String NAME  = "https://open.ys7.com/api/lapp/camera/name/update";


    /**
     *修改设备OSD名称地址
     */
    private final static String OSD  = "https://open.ys7.com/api/lapp/device/update/osd/name";

    public Page<BasicCameraDetail> pageList(RBasicCameraDetail.SearchBody search) {
        QBasicCameraDetail query = new QBasicCameraDetail();
        Opt.ofBlankAble(search.getStatus()).ifPresent(x -> query.status.eq(x?1:0));
        Opt.ofBlankAble(search.getCameraDirection()).ifPresent(x -> query.cameraDirection.eq(x));
        Opt.ofBlankAble(search.getDeviceSerial()).ifPresent(x -> query.deviceSerial.eq(x));
        Opt.ofBlankAble(search.getCameraStatus()).ifPresent(x -> query.cameraStatus.eq(x));
        Opt.ofBlankAble(search.getChannelName()).ifPresent(x -> query.channelName.contains(x));
        query.isEncrypt.eq(0).order().id.desc().setFirstRow(search.firstRow()).setMaxRows(search.maxRows());
        return new Page<BasicCameraDetail>().load(query.findPagedList());
    }

    public void update(Long id, RBasicCameraDetail.EditBody body) {
        BasicCameraDetail record = getOneById(id);
        Assert.notNull(record, ArcoTips.UPDATE_NOT_FOUND);
//        if (record.getChannelName().equals(body.getChannelName())){
//            record.setCameraDirection(body.getCameraDirection()).setChannelName(body.getChannelName()).update();
//            return;
//        }
        record.setCameraDirection(body.getCameraDirection()).setVideoLocation(body.getVideoLocation()).setChannelName(body.getChannelName());
        updateName(record,record.getChannelName());

    }
    /**
     * 获取摄像头直播地址
     *
     * @param id 摄像头id
     * @return {@link String}
     */
    public String getAddress(Long id) {
//        String url = cacheService.getCameraCache().get(id);
//        if (StrUtil.isBlank(url)) {
//            return getCameraUrl(getOneById(id),true);
//        }
        return getLive(getOneById(id));
    }

    /**
     * 获取拼接 可控地址
     * @param record
     * @return {@link String}
     */
    public String getLive(BasicCameraDetail record){
        String accessToken = cacheService.getCameraTokenCache().get("accessToken");
        String url = "ezopen://open.ys7.com/".concat(record.getDeviceSerial()).concat("/").concat(record.getChannelNo().toString()).concat(".hd.live");
        log.warn("url = {}",url);
        Map<String, String> token = Map.of("accessToken", accessToken, "url", url);
        return  JSONUtil.parse(token).toString();
    }


    public String getLiveHtml(BasicCameraDetail record){
        String accessToken = cacheService.getCameraTokenCache().get("accessToken");
        return "https://open.ys7.com/ezopen/h5/live" + "?autoplay=1" + "&audio=1" + "&accessToken=" + accessToken + "&hd=1" + "&deviceSerial=" + record.getDeviceSerial() + "&channelNo=" + record.getChannelNo();
    }


    public String getCameraUrl(BasicCameraDetail record,Boolean isRemind){
        if (ObjUtil.isEmpty(record)){
            return null;
        }
        String url = cacheService.getCameraCache().get(record.getId());
        if (StrUtil.isBlank(url)) {
            String accessToken = cacheService.getCameraTokenCache().get("accessToken");
            if (StrUtil.isBlank(accessToken)){
                accessToken = cameraTask.upToken();
                cacheService.getCameraTokenCache().put("accessToken", accessToken);
            }
            Assert.notNull(record, ArcoTips.UPDATE_NOT_FOUND);
            Map<String, Object> map = Map.of("accessToken", accessToken,"channelNo",record.getChannelNo(), "deviceSerial", record.getDeviceSerial(), "protocol", 2, "expireTime", 8200);
            HttpResponse execute = HttpRequest.post(LIVE).form(map).execute();
            JSON parse = JSONUtil.parse(execute.body());
            boolean code = ObjectUtil.equals(parse.getByPath("code"), "200");
            if (isRemind){
                Assert.isTrue(code, (String) parse.getByPath("msg"));
            }
            if (!code){
                return null;
            }
            url = (String) parse.getByPath("data.url");
            Opt.ofBlankAble(url).ifPresent(x -> cacheService.getCameraCache().put(record.getId(), x));
        }
        return url;
    }

    /**
     * 修改云端设备名称
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateName(BasicCameraDetail record, String name) {
        log.warn("修改云端设备名称=={}", name);
        String accessToken = cacheService.getCameraTokenCache().get("accessToken");
        Assert.notNull(record, ArcoTips.UPDATE_NOT_FOUND);
        String url  = "/?accessToken=".concat(accessToken).concat("&deviceSerial=".concat(record.getDeviceSerial()).concat("&name=").concat(name).concat("&channelNo=").concat(record.getChannelNo().toString()));
        log.warn(NAME.concat(url));
        HttpResponse execute = HttpRequest.post(NAME.concat(url)).header("Content-Type","application/x-www-form-urlencoded").execute();
        JSONObject object = new JSONObject(execute.body());
        log.warn("修改云端设备名称=={}", object);
        record.setChannelName(name).update();
        Assert.isTrue(ObjectUtil.equals(object.get("code"), "200"), (String) object.get("msg"));
    }

//    /**
//     * 修改云端设备Osd设备
//     */
//    public void updateOsdName(BasicCameraDetail record, String title) {
//        String accessToken = cacheService.getCameraTokenCache().get("accessToken");
//        Assert.notNull(record, ArcoTips.UPDATE_NOT_FOUND);
//        Map<String, Object> map = Map.of("accessToken", accessToken, "deviceSerial", record.getDeviceSerial() ,"osdName",title ,"channelNo",record.getChannelNo());
//        HttpResponse execute = HttpRequest.post(OSD).form(map).execute();
//        JSONObject object = new JSONObject(execute.body());
//        if (ObjectUtil.equals(object.get("code"), "200")){
//            log.error((String) object.get("msg"));
//        }
//    }


//    public static void main(String[] args) {
//        csUpdateOsdName();
//    }
//
//    public static void csUpdateOsdName() {
//        String builder = "猪猪名称:" + "我是猪猪名称" + "\n" +
//                "所属会员:" + "我是所属会员" + "\n" +
//                "猪猪编号:" + "我是猪猪编号" + "\n" +
//                "猪圈编号:" + "我是猪圈编号";
//
//        Map<String, Object> map = Map.of("accessToken", "at.690ot9fl234o5ho05ko6f3n04l5ji432-2h7zlehny3-0y0rj5r-nxkg3eaun", "deviceSerial","AW8689230" ,"osdName",builder ,"channelNo",1);
//        HttpResponse execute = HttpRequest.post(OSD).form(map).execute();
//        JSONObject object = new JSONObject(execute.body());
//        if (ObjectUtil.equals(object.get("code"), "200")){
//            log.error((String) object.get("msg"));
//        }
//    }


    /**
     * 获取一个数据
     *
     * @param id id
     * @return {@link BasicCameraDetail}
     */
    private BasicCameraDetail getOneById(Long id) {
        QBasicCameraDetail query = new QBasicCameraDetail();
        BasicCameraDetail record = query.id.eq(id).setMaxRows(1).findOne();
        Assert.notNull(record, ArcoTips.NOT_FOUND);
        return record;
    }
    /**
     * 刷新摄像头
     */
    public TaskResult refreshCamera(){
        return cameraTask.earTagData();
    }

    /**
     * 获取数据字典下拉选项
     * @return {@code List<SelectOption>}
     */
    public List<SelectOption> getOptions() {
        QBasicCameraDetail place = new QBasicCameraDetail().status.eq(1).cameraDirection.ne(CameraDirection.UNKNOWN).cameraStatus.eq(CameraStatus.NOT_BOUND); //查找在线的摄像头并且是未绑定的
        return place.findStream()
                .map(x -> new SelectOption().setLabel(x.getCameraDirection().getLabel().concat("_").concat(x.getChannelName())).setValue(x.getPassageId()).setDisabled(false))
                .collect(Collectors.toList());
    }


}






